﻿//ITradeStatisticParameter.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Algo.Statistics
{
	using System;
	using System.ComponentModel;

	using Ecng.Serialization;

	using StockSharp.Algo.PnL;

	/// <summary>
	/// Интерфейс, описывающий параметр статистики, рассчитывающийся на основе сделки.
	/// </summary>
	public interface ITradeStatisticParameter
	{
		/// <summary>
		/// Добавить в параметр информацию о новой сделке.
		/// </summary>
		/// <param name="info">Информация о новой сделке.</param>
		void Add(MyTradePnLInfo info);
	}

	/// <summary>
	/// Количество выигранных сделок (прибыль которых больше 0).
	/// </summary>
	[DisplayName(@"Количество выигранных сделок")]
	public class WinningTradesParameter : BaseStatisticParameter<int>, ITradeStatisticParameter
	{
		/// <summary>
		/// Добавить в параметр информацию о новой сделке.
		/// </summary>
		/// <param name="info">Информация о новой сделке.</param>
		public void Add(MyTradePnLInfo info)
		{
			if (info == null)
				throw new ArgumentNullException("info");

			if (info.PnL <= 0)
				return;

			Value++;
		}
	}

	/// <summary>
	/// Количество проигранных сделок и с нулевой прибылью (прибыль которых меньше равна 0).
	/// </summary>
	[DisplayName(@"Количество проигранных сделок и с нулевой прибылью")]
	public class LossingTradesParameter : BaseStatisticParameter<int>, ITradeStatisticParameter
	{
		/// <summary>
		/// Добавить в параметр информацию о новой сделке.
		/// </summary>
		/// <param name="info">Информация о новой сделке.</param>
		public void Add(MyTradePnLInfo info)
		{
			if (info == null)
				throw new ArgumentNullException("info");

			if (info.ClosedVolume > 0 && info.PnL <= 0)
				Value++;
		}
	}

	/// <summary>
	/// Общее количество сделок.
	/// </summary>
	[DisplayName(@"Общее количество сделок")]
	public class TradeCountParameter : BaseStatisticParameter<int>, ITradeStatisticParameter
	{
		/// <summary>
		/// Добавить в параметр информацию о новой сделке.
		/// </summary>
		/// <param name="info">Информация о новой сделке.</param>
		public void Add(MyTradePnLInfo info)
		{
			Value++;
		}
	}

	/// <summary>
	/// Общее количество закрывающих сделок.
	/// </summary>
	[DisplayName(@"Общее количество закрывающих сделок")]
	public class RoundtripCountParameter : BaseStatisticParameter<int>, ITradeStatisticParameter
	{
		/// <summary>
		/// Добавить в параметр информацию о новой сделке.
		/// </summary>
		/// <param name="info">Информация о новой сделке.</param>
		public void Add(MyTradePnLInfo info)
		{
			if (info.ClosedVolume > 0)
				Value++;
		}
	}

	/// <summary>
	/// Cредняя величина прибыли сделки.
	/// </summary>
	[DisplayName(@"Cредняя величина прибыли сделки")]
	public class AverageTradeParameter : BaseStatisticParameter<decimal>, ITradeStatisticParameter
	{
		private decimal _sum;
		private int _count;

		/// <summary>
		/// Добавить в параметр информацию о новой сделке.
		/// </summary>
		/// <param name="info">Информация о новой сделке.</param>
		public void Add(MyTradePnLInfo info)
		{
			if (info == null)
				throw new ArgumentNullException("info");

			if (info.ClosedVolume == 0)
				return;

			_sum += info.PnL;
			_count++;

			Value = _count > 0 ? _sum / _count : 0;
		}

		/// <summary>
		/// Сохранить состояние параметра статистики.
		/// </summary>
		/// <param name="storage">Хранилище.</param>
		public override void Save(SettingsStorage storage)
		{
			storage.SetValue("Sum", _sum);
			storage.SetValue("Count", _count);

			base.Save(storage);
		}

		/// <summary>
		/// Загрузить состояние параметра статистики.
		/// </summary>
		/// <param name="storage">Хранилище.</param>
		public override void Load(SettingsStorage storage)
		{
			_sum = storage.GetValue<decimal>("Sum");
			_count = storage.GetValue<int>("Count");

			base.Load(storage);
		}
	}

	/// <summary>
	/// Средняя выигрышная сделка.
	/// </summary>
	[DisplayName(@"Средняя выигрышная сделка")]
	public class AverageWinTradeParameter : BaseStatisticParameter<decimal>, ITradeStatisticParameter
	{
		private decimal _sum;
		private int _count;

		/// <summary>
		/// Добавить в параметр информацию о новой сделке.
		/// </summary>
		/// <param name="info">Информация о новой сделке.</param>
		public void Add(MyTradePnLInfo info)
		{
			if (info == null)
				throw new ArgumentNullException("info");

			if (info.ClosedVolume == 0)
				return;

			if (info.PnL > 0)
			{
				_sum += info.PnL;
				_count++;
			}

			Value = _count > 0 ? _sum / _count : 0;
		}

		/// <summary>
		/// Сохранить состояние параметра статистики.
		/// </summary>
		/// <param name="storage">Хранилище.</param>
		public override void Save(SettingsStorage storage)
		{
			storage.SetValue("Sum", _sum);
			storage.SetValue("Count", _count);

			base.Save(storage);
		}

		/// <summary>
		/// Загрузить состояние параметра статистики.
		/// </summary>
		/// <param name="storage">Хранилище.</param>
		public override void Load(SettingsStorage storage)
		{
			_sum = storage.GetValue<decimal>("Sum");
			_count = storage.GetValue<int>("Count");

			base.Load(storage);
		}
	}

	/// <summary>
	/// Средняя проигрышная сделка.
	/// </summary>
	[DisplayName(@"Средняя проигрышная сделка")]
	public class AverageLossTradeParameter : BaseStatisticParameter<decimal>, ITradeStatisticParameter
	{
		private decimal _sum;
		private int _count;

		/// <summary>
		/// Добавить в параметр информацию о новой сделке.
		/// </summary>
		/// <param name="info">Информация о новой сделке.</param>
		public void Add(MyTradePnLInfo info)
		{
			if (info == null)
				throw new ArgumentNullException("info");

			if (info.ClosedVolume == 0)
				return;

			if (info.PnL <= 0)
			{
				_sum += info.PnL;
				_count++;
			}

			Value = _count > 0 ? _sum / _count : 0;
		}

		/// <summary>
		/// Сохранить состояние параметра статистики.
		/// </summary>
		/// <param name="storage">Хранилище.</param>
		public override void Save(SettingsStorage storage)
		{
			storage.SetValue("Sum", _sum);
			storage.SetValue("Count", _count);

			base.Save(storage);
		}

		/// <summary>
		/// Загрузить состояние параметра статистики.
		/// </summary>
		/// <param name="storage">Хранилище.</param>
		public override void Load(SettingsStorage storage)
		{
			_sum = storage.GetValue<decimal>("Sum");
			_count = storage.GetValue<int>("Count");

			base.Load(storage);
		}
	}
}